
local jass = require "jass.common"
local jy_data = load_excel('数值投放.xlsx','精英数量')

local enemy_count = {}
for a,da in ipairs(load_excel('数值投放.xlsx','刷怪速度')) do
    enemy_count[a] = da['刷怪速度']
end

--[[
数值获取
]]
local unit_weight = {}
local jy_weight = {}
for k,v in pairs(load_excel('数值投放.xlsx','怪物参数')) do
    local skill = {}
    table.insert(skill,v['技能1'])
    table.insert(skill,v['技能2'])
    v.skill = skill
    v.types = v['类型']

    ac.lni('unit',k,v)
    if v['阶段'] and v['类型']=='普通' then
        local lv = v['阶段']
        for a=lv,4 do
            if not unit_weight[a] then
                unit_weight[a] = {}
            end
            table.insert(unit_weight[a],{k,v['随机权重']})
        end
    end
    if v['阶段'] and v['类型']=='精英' then
        local lv = v['阶段']
        for a=lv,4 do
            if not jy_weight[a] then
                jy_weight[a] = {}
            end
            table.insert(jy_weight[a],{k,v['随机权重']})
        end
    end
end


local mt = {}
mt.hard = 0
--天数
mt.day = 0
--白天
mt.time1 = 0.1
--黑夜时间
mt.time2 = 120
--
mt.unit_max = 200
mt.max_level = 16

mt.rect = ac.rect.j_rect('base')
mt.base = mt.rect:center()
mt.kill_count = 0
mt.index = 0
mt.speed = 1
 
ac.player.__index.speed = 1
ac.player.__index.kill_count = 0
ac.player.__index.unit_count = 0

function ac.player.__index:add_enemy(name,ex)
    local point = self.rect1:random()
    local owner = ac.player[self.id + 8]
    if self.unit_count>=40 and ex==nil then
        return
    end
    local unit = owner:create_unit(name,point)
    jass.RemoveGuardPosition(unit.handle)
    unit:set('索敌范围',3000)
    self.units[unit.handle] = unit
    self.unit_count = self.unit_count + 1
    unit:event '单位-死亡'(function()
        self.units[unit.handle] = nil
        self.kill_count = self.kill_count + 1
        self.unit_count = self.unit_count - 1
    end)
    unit:issue_order('attack',ac.enemy.base)
    unit:loop(30*1000,function()
        unit:issue_order('attack',ac.enemy.base)
    end)
    return unit
end

--添加怪物
function mt:add_unit(name,point,ex)
    local name = name or table.get_by_weight(self.unit_weight)
    local point = point or self.base - {math.random(360),2500}
    local owner = ac.player[8]
    local unit = owner:create_unit(name,point)
    jass.RemoveGuardPosition(unit.handle)
    unit:set_enemy_level(self.day)
    unit:issue_order('attack',self.base)
    return unit
end


--晚上-开始刷怪
local boss = {
    --'深渊触手',
    '黑暗大鱼',
    '娜迦女王',
    '玄武',
}
local boss_hp = {
    0,60,120,180,
}
function mt:night()
    self:clear()
    local move_speed = 50 * (math.ceil(self.day/4)-1)
    if self.day~=self.max_level then
        ac.each_player(function(player)
            player:get_data('额外刷怪速度',0)
        end)
        self.timer_jl1 = ac.loop(30*1000,function()
            if self.day>=5 and math.random(100)<=25 then
                self.speed = self.speed + 1
                ac.player.self:send_msg('|cffff0000深海传来呓语，怪物们暴走了|r')
                ac.wait(30*1000,function()
                    self.speed = self.speed - 1
                end)
            end

            ac.each_player(function(player)
                if player.kill_count>50 then
                    player:get_data('额外刷怪速度',math.min(player:get_data('额外刷怪速度',0) + 1,4))
                end
                player.kill_count = 0
            end)
        end)
        self.timer_jl1:on_timer()

        local ex_lv = 0
        self.timer_jl2 = ac.loop(500,function()
            ex_lv = math.ceil(math.min(ex_lv + 0.4,99))
            ac.each_player(function(player)
                local count = ((player:get_data('额外刷怪速度',0) + player:get_data('刷怪速度',0) + (enemy_count[self.day] or enemy_count[#enemy_count])) * self.speed)/2 + player:get_data('保留刷怪',0)
                local num = math.floor(count)
                for a=1,num do
                    local name = table.get_by_weight(self.unit_weight)
                    local unit = player:add_enemy(name)
                    if unit then
                        unit:set_enemy_level(self.day,nil,ex_lv)
                        unit.ui_title = ''
                        unit_add_life2(unit)
                        unit:add('移动速度',move_speed)
                    end
                end
                player:set_data('保留刷怪',count - num)
            end)
        end)

        local data = jy_data[self.day] or {}
        local num = data[self.hard_name] or 0
        self.exit_timer0 = ac.timer((self.time2/(num+1)*1000),num,function()
            ac.each_player(function(player)
                local name = table.get_by_weight(self.jy_unit)
                local unit = player:add_enemy(name)
                if unit then
                    unit.owner_player = player
                    unit:set_enemy_level(self.day)
                    unit:add('移动速度',move_speed)
                    japi.EXSetUnitMoveType(unit.handle, 16)
                    unit:add_buff '怪物-自动施法'{}
                end
                
            end)
        end)
        
        self.exit_timer2 = ac.wait(self.time2*1000,function()
            self:sunup()
        end)
        ac.game:notify('游戏-进入黑夜',self.day)
        ac.game:notify('游戏-设置顶部计时',self.title,self.exit_timer2,'下一天：')
    end

    if self.day%4==0 then
        local level = self.day
        local boss_data = ('Boss%0.f'):format(level/4)
        ac.game:notify('游戏-刷新Boss')
        ac.player.self:cinematic_filter{
            start = {100,0,0,0},
            finish = {100,0,0,100},
            time = 2,
        }
        ac.wait(2000,function()
            jass.DisplayCineFilter(false)
        end)
        ac.wait(2000,function()
            
            if self.day==self.max_level then
                self:clear()
                ac.each_player(function(player)
                    player:set_camera(self.base)
                    for handle,unit in pairs(player.units) do
                        unit:remove()
                    end
                end)
                local last = self.day==self.max_level
                local life_add = boss_hp[ac.player.online_count] or boss_hp[#boss_hp]
                local u = self:add_unit('克苏鲁',self.base,true)
                
                ac.game:notify('游戏-隐藏商店')
                u:set_enemy_level(self.day,boss_data)
                u:add('生命上限%',life_add)
                u:add_buff '排行榜'{}
                u:add_buff 'Boss出场'{time = 4}
                u:add_buff '怪物-自动施法'{}
                u:event '单位-死亡'(function()
                    self:clear()
                    ac.game:notify('游戏-游戏胜利',self)
                    ac.game:notify('游戏-击杀Boss',self,level)
                end)
                self.exit_timer3 = ac.wait(120*1000,function()
                    self:clear()
                    ac.game:notify('游戏-游戏失败',self)
                end)
                ac.game:notify('游戏-设置顶部计时',self.title,self.exit_timer3,'限时：')
            else
                local name = table.remove(boss,math.random(#boss))
                ac.each_player(function(player)
                    local unit = player:add_enemy(name,true)
                    if unit then
                        unit:set_enemy_level(self.day,boss_data)
                        unit:issue_order('attack',self.base)
                        unit:loop(30*1000,function()
                            unit:issue_order('attack',self.base)
                        end)
                        unit:add_buff '怪物-自动施法'{}
                        unit:event '单位-死亡'(function()
                            player:notify('游戏-创建金猪',player,unit:get_point(),level)
                        end)
                    end
                end)
            end
        end)
        
    end
    ac.game:notify('游戏-新的一天',self.day)
end

--白天
function mt:sunup(time)
    local time = time or self.time1
    self:clear()
    self.day = self.day + 1
    self.title = ('难%s | 第%s/%s天'):format(self.hard,self.day,self.max_level)
    local lv = math.ceil(self.day/4)
    self.unit_weight = unit_weight[lv]
    self.jy_unit = jy_weight[lv]
    self.exit_timer1 = ac.wait(time*1000,function()
        self:night()
    end)
    ac.game:notify('游戏-发工资',self.day)
    -- ac.game:notify('游戏-设置顶部计时',self.title,self.exit_timer1,'白天：')
    ac.game:notify('游戏-设置顶部计时',self.title,self.exit_timer1,'准备：')
end


function mt:clear()
    if self.exit_timer0 then self.exit_timer0:remove() end
    if self.exit_timer1 then self.exit_timer1:remove() end
    if self.exit_timer2 then self.exit_timer2:remove() end
    if self.exit_timer3 then self.exit_timer3:remove() end
    if self.timer_jl1 then self.timer_jl1:remove() end
    if self.timer_jl2 then self.timer_jl2:remove() end
    if self.timer_sb then self.timer_sb:remove() end
    --for u in pairs(self.units) do
    --    u:remove()
    --end
end

function mt:init()
    self.units = {}
    self:sunup(10)
    ac.each_player(function(player)
        player.units = {}

        local unit = ac.player[player.id+8]:create_unit('腐化塔',player.rectT:center())
        local unit2 = ac.player[player.id+8]:create_unit('海神祭坛',player.rect2:center())
        unit2:add_restriction '无敌'
        unit2:add_buff '脱战回血'{}

        local unit3 = ac.player[player.id+8]:create_unit('海魔触手',player.rect3:center())
        unit3:add_restriction '无敌'
        unit3:add_buff '脱战回血'{}
        unit.effect = ac.hint_white2(unit:get_point(),unit:get('攻击距离'))
        unit.effect:set_color(100,0,0)
        unit.effect:set_visible(false)


        unit:set_enemy_level(unit['默认等级'])
        unit:event '单位-死亡'(function()
            local hero = player.hero
            unit.effect:remove()
            unit2:remove_restriction '无敌'
            player:send_msg('击破腐化塔，刷怪速度+2，奖励:|cff00ff00200木材|r和|cffffff003点每秒金币|r')
            player:add('木材',200)
            player:get_data('刷怪速度',player:get_data('刷怪速度',0) + 2)
            if hero then
                hero:add('每秒金币',3)
            end
        end)
        unit:event '单位-攻击'(function(_,_,target)
            target:add_buff '显示伤害范围'{time = 2,source = unit}
        end)

        
        unit2.effect = ac.hint_white2(unit2:get_point(),unit2:get('攻击距离'))
        unit2.effect:set_color(100,0,0)
        unit2.effect:set_visible(false)
        unit2:set_enemy_level(unit2['默认等级'])
        unit2:event '单位-死亡'(function()
            local hero = player.hero
            unit2.effect:remove()
            unit3:remove_restriction '无敌'
            player:send_msg('击破祭坛，刷怪速度+1，奖励:|cff00ff00500木材|r')
            player:add('木材',500)
            player:get_data('刷怪速度',player:get_data('刷怪速度',0) + 1)
        end)
        unit2:event '单位-攻击'(function(_,_,target)
            target:add_buff '显示伤害范围'{time = 2,source = unit2}
        end)

        unit3:set_enemy_level(unit2['默认等级'])
        unit3:event '单位-死亡'(function()
            
        end)

    end)
end


ac.game:event '游戏-设置难度'(function(_,hard)
    local data = setmetatable({}, {__index = mt})
    ac.enemy = data
    data.hard = hard
    data.hard_name = ('难%s'):format(hard)
    data:init()
end)

ac.game:event '游戏-游戏胜利'(function()
    if ac.enemy then
        ac.enemy:clear()
        for unit in ac.selector('unit')
            : range(ac.point(0,0),9999)
            : can_god()
            : loop()
        do
            if unit.owner.id>=8 then
                unit:remove()
            end
        end
    end
end)


ac.game:event '游戏-游戏失败'(function()
    for unit in ac.selector('unit')
        : range(ac.point(0,0),9999)
        : loop()
    do
        unit:add_restriction '硬直'
        unit:add_restriction '无敌'
    end
end)


local buff = ac.buff['Boss出场']
buff.model2 = [[4ba42c4078ddc07409f0afed579f495d.mdl]]
buff.time = 4
buff.fade = 1
buff.pulse = 0.03
function buff:on_pulse()
    local h = math.min(- ((self:get_remaining())/(self.time - self.fade)) * 400,0)
    self.effect:set_height(h + self.height)
end

function buff:on_add()
    local unit = self.target
    local point = unit:get_point()
    self.height = point:get_height()
    ac.player.self:noise(5,self.time)
    unit:add_restriction '隐藏'
    unit:add_restriction '无敌'
    unit:add_restriction '硬直'
    self.effect = point:effect{
        model = unit:get_model(),
        size = unit:get_slk('modelScale',1) * (unit['模型大小'] or 1),
        hide_when_remove = true,
        angle = 270,
    }
    self:on_pulse()
    self:gc(self.effect)
    self:gc(point:effect{
        model = self.model2,
        size = 1,
    })
    self:gc(function()
        unit:remove_restriction '隐藏'
        unit:remove_restriction '无敌'
        unit:remove_restriction '硬直'
    end)
end

local buff = ac.buff['显示伤害范围']

function buff:on_add()
    local source = self.source
    local target = self.target
    local player = target.owner
    local effect = source.effect
    if player:is_self() then
        effect.show_count = (effect.show_count or 0) + 1
        effect:set_visible(true)
    end
    self:gc(function()
        if player:is_self() then
            effect.show_count = (effect.show_count or 0) - 1
            if effect.show_count<=0 then
                effect:set_visible(false)
            end
        end
    end)
end

local buff = ac.buff['脱战回血']
buff.pulse = 1
function buff:on_pulse()
    local hero = self.owner
    if not hero:is_fight_active() then
        hero:add('生命',hero:get('生命上限') * 0.05)
    end
end

